<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        html,
        body {
            margin: 0;
            padding: 0;
            background-color: #999;
        }
        
        .fileInput {
            margin: 12px 0;
            background-color: #ccc;
        }
    </style>
</head>

<body>
    <div class="fileInput">
        <input type="file" accept="image/*" id="fileInput" />
    </div>
    <div class="canvasShootContainer">
        <canvas class="shoot"></canvas>
    </div>
    <div class="canvasShowContainer">
        <canvas class="show"></canvas>
    </div>
    <script>
        // 获取所需的所有元素
        const fileInput = document.querySelector("#fileInput");
        const canvasShootContainer = document.querySelector(
            ".canvasShootContainer"
        );
        const canvasShowContainer = document.querySelector(
            ".canvasShowContainer"
        );
        const canvasShoot = document.querySelector(".shoot");
        const canvasShow = document.querySelector(".show");
        const ctx = canvasShoot.getContext("2d");
        const ctx2 = canvasShow.getContext("2d");

        const opacity = 0.5; // 设置蒙层透明度
        let drawPosition = []; //设置位置信息:  在画布中的起始位置,  截图的大小
        const img = new Image(); // 创建图片 用来获取图片信息

        function init() {
            setEvent(); //给元素绑定事件
        }

        function setEvent() {
            fileInput.addEventListener("change", handleFileInputChange, false);
            canvasShoot.addEventListener("mousedown", handleCanvasMouseDown, false);
        }

        function handleCanvasMouseDown(e) {
            console.log(e, "55");
            let startX = e.offsetX;
            let startY = e.offsetY;
            drawPosition = [startX, startY];
            console.log(drawPosition);

            canvasShoot.addEventListener("mousemove", handleCanvasMouseMove, false);
            canvasShoot.addEventListener("mouseup", handleCanvasMouseUp, false);
        }

        function handleCanvasMouseMove(e) {
            let endX = e.offsetX;
            let endY = e.offsetY;
            let [startX, startY] = drawPosition;
            const drawWidth = endX - startX;
            const drawHeight = endY - startY;
            drawPosition = [startX, startY, drawWidth, drawHeight];
            console.log(drawPosition);

            // 获取画布大小
            const {
                width,
                height
            } = canvasShoot;

            // 清理画布
            ctx.clearRect(0, 0, width, height);

            // 绘制蒙层
            drawMask(width, height, opacity);

            // 绘制截取区域
            setShootArea(width, height, drawPosition);
        }

        function handleCanvasMouseUp() {
            canvasShoot.removeEventListener(
                "mousemove",
                handleCanvasMouseMove,
                false
            );
            canvasShoot.removeEventListener("mouseup", handleCanvasMouseUp, false);
        }

        function handleFileInputChange(e) {
            const file = e.target.files[0];
            // 获取解析文件实例
            const reader = new FileReader();
            // 解析文件信息, 在result中获取 base64 信息
            reader.readAsDataURL(file);
            reader.onload = (e) => {
                let result = e.target.result;

                img.src = result;
                img.onload = function() {
                    // this指向img对象
                    console.log(this.width, this.height);
                    const {
                        width,
                        height
                    } = this;
                    // 根据图片的大小设置画布容器, 及画布的大小
                    generateCanvas(canvasShootContainer, canvasShoot, width, height);
                    // 在画布中绘制图片
                    ctx.drawImage(img, 0, 0);
                    // 绘制蒙版
                    drawMask(width, height, opacity);
                };
            };
        }

        function generateCanvas(
            canvasShootContainer,
            canvasShoot,
            width,
            height
        ) {
            canvasShootContainer.style.width = width + "px";
            canvasShootContainer.style.height = height + "px";
            canvasShoot.width = width;
            canvasShoot.height = height;
            canvasShootContainer.style.display = "block";
        }

        //绘制蒙层
        function drawMask(width, height, opacity) {
            ctx.fillStyle = `rgba(0,0,0,${opacity})`;
            ctx.fillRect(0, 0, width, height);
        }

        function setShootArea(width, height, drawPosition) {
            if (!drawPosition.length) return;

            ctx.globalCompositeOperation = "destination-out";
            ctx.fillStyle = "#000";
            ctx.fillRect(...drawPosition);

            ctx.globalCompositeOperation = "destination-over";
            ctx.drawImage(img, 0, 0, width, height, 0, 0, width, height);
        }

        init();
    </script>
</body>

</html>